#pragma once
#include <list>
#include <memory>
#include "type.h"
#include <iostream>
#include <log.h>
#include <string>
#include <mutex>
#include <queue>
#include <map>
#include <iostream>
#include <chrono>
#include <file.h>
// 导入ffmpeg相关头文件
extern "C"
{
#include "libavdevice/avdevice.h"
#include "libavcodec/avcodec.h"
#include "libswscale/swscale.h"
#include "libswresample/swresample.h"
#include "libavutil/imgutils.h"
#include <libavutil/audio_fifo.h>
#include <libavfilter/buffersink.h>
#include <libavfilter/buffersrc.h>
#include <libavutil/common.h>
}

// 不涉及分辨率转码码率装换等
namespace Media
{
	class DecoderEncoder 
	{
		
	public:
		DecoderEncoder(
			AVStream *in_video_stream,
			AVStream *in_audio_stream,
			enum AVCodecID video_codec = AV_CODEC_ID_H264,
			enum AVCodecID audio_codec = AV_CODEC_ID_AAC
		);
		~DecoderEncoder();
		// 启动
		bool start();
		// 是否需要音频转码
		bool isTranslaterAudioCodec(AVCodecContext** p_codec_ctx);
		// 是否需要视频转码
		bool isTranslaterVideoCodec(AVCodecContext** p_codec_ctx);
		// 送入一帧,输出好几帧
		bool addPacket(const enum AVMediaType &type,
			const AVPacket* packet,
			std::queue< std::shared_ptr<AVPacket> >& packet_out);

	protected:
		// 检查是否需要进行转码
		bool checkNeedTranslater(AVStream* stream, enum AVCodecID codec_id);
		// 如果需要转码,生成解码器
		bool createDecoderCodec(AVCodecContext** codec_context, AVStream* stream);
		// 如果需要转码,生成编码器
		bool createEncoderCodec(AVStream* stream,		// 输入码流
			AVCodecContext** encoder_context,				// 编码器
			AVCodecContext* decoder_context, enum AVCodecID codec_id);
		// 解码一帧
		bool encoderFrame(const enum AVMediaType& type,
			const std::shared_ptr<AVFrame> &frame,
			std::queue< std::shared_ptr<AVPacket> >& packet_out);
		// 解码出来的数据过滤镜
		bool filterFrame(const enum AVMediaType& type,
			const std::shared_ptr<AVFrame>& frame,
			std::queue< std::shared_ptr<AVPacket> >& packet_out);
	private:
		// 初始化音频滤镜
		bool init_audio_filters();
		
	private:
		/***********************视频编解码相关************************/
		// 输入视频流用于拷贝编解码参数
		AVStream* p_in_video_stream = nullptr;
		// 视频预期编码
		enum AVCodecID m_video_out_codec = AV_CODEC_ID_NONE;
		// 视频解码器
		AVCodecContext *p_video_decoder_codec_ctx = nullptr;
		// 视频编码器
		AVCodecContext* p_video_encoder_codec_ctx = nullptr;
		bool m_video_translate = false;




		/***********************音频编解码相关************************/
		// 输入音频流用于拷贝编解码参数
		AVStream* p_in_audio_stream = nullptr;
		// 音频预期编码
		enum AVCodecID m_audio_out_codec = AV_CODEC_ID_NONE;
		// 音频解码器
		AVCodecContext* p_audio_decoder_codec_ctx = nullptr;
		// 音频编码器
		AVCodecContext* p_audio_encoder_codec_ctx = nullptr;
		bool m_audio_translate = false;
		// 音频缓冲队列，防止一帧采样点较大无法处理
		AVAudioFifo* p_audio_fifo = nullptr;
		// 音频采样点总数
		int64_t m_audio_sample_count = 0;
		// 视频帧个数
		int64_t m_video_sample_count = 0;

		// 音频滤镜
		AVFilterContext* p_audio_src_flt_ctx = nullptr;
		AVFilterContext* p_audio_sink_flt_ctx = nullptr;
	};
}


